# -*- coding: cp1252 -*-
from SimPy.Simulation import *
#
#  en este ejemplo se usaran dos recursos para simular dos puertas
#  de ingreso. Los carros hacen cola en esas puertas para otener
#  su ticket de parqueo. Por ello, cuando llega un carro puede
#  seleccionar la puerta que tiene la cola más corta

#  los atributos de un resource R:
#     R.waitQ  elementos que estan haciendo
#             cola para utilizar el recuros.
#     R.activeQ  elementos que estan siendo
#             atendidos por este recurso.

from random import uniform
from random import Random, randint


class Banco(Process):
    def __init__(self,id):
        Process.__init__(self)
        self.id=id
        
    def carDriving(self,driveTime,parkTime):
        yield hold,self,driveTime
        ahora= now()
        self.llega = now()
        # ahora decide que ventanilla usara para ingresar:
        # aquella que tenga menor número de carros en su cola

        carrosxventanilla = [ len(ventanillas[0].waitQ) + len(ventanillas[0].activeQ),len(ventanillas[1].waitQ) + len(ventanillas[1].activeQ), len(ventanillas[2].waitQ) + len(ventanillas[2].activeQ), len(ventanillas[3].waitQ) + len(ventanillas[3].activeQ)]
        
        for i in range(4): #hay dos ventanillas
            if carrosxventanilla[i] == 0 or carrosxventanilla[i] == min(carrosxventanilla):
                self.ventanilla = i  #escogemos la ventanilla que no tiene carros o
                            #cuya cola es la menor
                break
            
        print "el cliente ",self.id," hace cola en ventanilla ", self.ventanilla    
        yield request,self,ventanillas[self.ventanilla] #esperamos pasar por la ventanilla
        print "%5.1f %s toma ticket en ventanilla %d" %(now(),self.id, self.ventanilla)
        yield hold, self, parkTime       # nos tardamos 1 unidad de tiempo tomando el ticket
        print "%5.1f %s pasa ventanilla %d" %(now(),self.id, self.ventanilla)
        yield release, self, ventanillas[self.ventanilla]

        # ya ingreso, ahora a buscar un parqueo:
        yield request,self,parkingLot
        print "%5.1f %s turno de " %(now(),self.id)
        yield hold,self,parkTime
        tiempoTotal = now() - ahora
        wt.observe(tiempoTotal)
        print "%5.1f %s se va del banco despues de  %5.1f tiempo total en el banco= %5.1f" %(now(),self.id,parkTime,tiempoTotal)
        yield release,self,parkingLot 

wt=Monitor()
initialize()
nrCars=150
parkingLot=Resource(capacity=4,qType=FIFO)
#ahora definimos las dos ventanillas, como recursos. Las colocamos
#en una lista, por si en el futuro definimos más ventanillas.
ventanillas = [Resource(capacity=1,name="ventanilla1"), Resource(capacity=1,name="ventanilla2"), Resource(capacity=1,name="ventanilla3"), Resource(capacity=1,name="ventanilla4")]
r = Random(12345)

for i in range(nrCars):
    c=Banco(id="cliente "+ str(i))
    activate(c,c.carDriving(driveTime=10,parkTime=r.randint(1,480)))
simulate(until=480)
        
        asdfa

print "Tiempo total en el banco: \tmean = %5.1f, \n\t\tvarianza=%2d"%(wt.mean(),wt.var())
